#ifndef CIPHER_H
#define CIPHER_H
#include <botan/symkey.h>
#include <botan/secmem.h>
#include <botan/cipher_mode.h>
#include <botan/auto_rng.h>

#include "utils/enums.h"


namespace crypto {
class Cipher {
public:
	Cipher();

	// Method to choose cipher algorithm
	bool chooseCipher(utils::CipherAlgorithm algorithm, Botan::Cipher_Dir direction);

	// Method to set IV
	void setIV(const Botan::secure_vector<uint8_t>& iv);

	// Method to save IV to file
	void saveIVinFile(const std::string& filename) const;

	// Method to save IV to ByteArray
	void saveIVInByteArray(Botan::secure_vector<uint8_t>& data) const;

	// Method to load IV from file
	bool loadIV(const std::string& filename, std::size_t ivSize);

	void generateIvWithSaving(std::size_t size);

	static Botan::InitializationVector generateIV(std::size_t size);

	// Method to encrypt data with IV
	Botan::secure_vector<uint8_t> encrypt(const Botan::SymmetricKey& key,
		const Botan::secure_vector<uint8_t>& plaintext) const;

	// Method to decrypt data with IV
	Botan::secure_vector<uint8_t> decrypt(const Botan::SymmetricKey& key,
		const Botan::secure_vector<uint8_t>& ciphertext) const;


	Botan::secure_vector<uint8_t> updateEncryption(const Botan::SymmetricKey& key,
			const Botan::InitializationVector& newIV, const Botan::secure_vector<uint8_t>& plaintext,
			utils::CipherAlgorithm algorithm = utils::CipherAlgorithm::Kuznyechik_CBC);



private:
	std::unique_ptr<Botan::RandomNumberGenerator> rng;
	std::unique_ptr<Botan::Cipher_Mode> cipher;
	Botan::InitializationVector iv;
};
}
#endif // CIPHER_H
